package com.wcl.hencodertest.batteryMeterView;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;

import androidx.annotation.Nullable;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.SizeUtils;

/**
 * @项目名： HenCoderTest
 * @包名： com.wcl.hencodertest.batteryMeterView
 * @文件名: BatteryView
 * @创建者: kilin
 * @创建时间: 2020/6/25 14:55
 * @描述： 电池View, 注意给的宽高最好相等
 */
public class BatteryView extends View {
    private static final String TAG = "BatteryView";
    /**
     * 低电量阈值,低于此电量,修改电池颜色为低电量颜色
     */
    public static final int LOW_POWER_THRESHOLD = 20;

    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    /**
     * 默认不旋转,如果旋转的话,请给90度的倍数[0,90,180,270]
     */
    private int rotateAngle = 0;

    /**
     * 外部框的颜色
     */
    private int outRectColor = Color.BLACK;

    /**
     * 内部框的颜色
     */
    private int innerRectColor = Color.BLACK;

    /**
     * 电池低电量的颜色
     */
    private int lowPowerColor = Color.RED;

    /**
     * 内部矩形充电的颜色
     */
    private int chargeColor = Color.GREEN;

    /**
     * 充电的闪电颜色
     */
    private int lightningColor = Color.WHITE;

    /**
     * 电池外部矩形的宽
     */
    private int outRectWidth = SizeUtils.dp2px(22);

    /**
     * 电池外部矩形的高
     */
    private int outRectHeight = SizeUtils.dp2px(12);

    /**
     * 电池外部矩形线条的粗细
     */
    private int outRectStrokeWidth = SizeUtils.dp2px(1);

    /**
     * 电池外部矩形的圆角半径
     */
    private int outRectRound = SizeUtils.dp2px(1);

    /**
     * 电池内部矩形的宽
     */
    private int innerRectWidth = SizeUtils.dp2px(19);

    /**
     * 电池内部矩形的高
     */
    private int innerRectHeight = SizeUtils.dp2px(9);

    /**
     * 电池阳极突出的宽度
     */
    private int anodeWidth = SizeUtils.dp2px(1);

    /**
     * 电池阳极的圆角
     */
    private int anodeRound = SizeUtils.dp2px(0.75F);

    /**
     * 电池阳极高度
     */
    private int anodeHeight = SizeUtils.dp2px(3);

    /**
     * 电池阳极绘制的path
     */
    Path anodePath = new Path();

    /**
     * 电池整个是否要缩放,如果尺寸不是58*58,那么会缩放,以上尺寸对应的view大小为58*58
     */
    private float scale = 1F;
    /**
     * 电池总宽(不包含缩放)
     */
    private int batteryWidth;

    /**
     * 电池总高(不包含缩放)
     */
    private int batteryHeight;

    /**
     * 当前电量百分比
     */
    private int batteryPercent = 0;

    /**
     * 是否在充电
     */
    private boolean isCharging = false;

    /**
     * 充电动画百分比
     */
    private float chargePercent = 1F;

    /**
     * 充电的动画
     */
    private ObjectAnimator animator;


    public BatteryView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //自身要求的宽度
        batteryWidth = outRectWidth + anodeWidth;
        //自身要求的高度
        batteryHeight = outRectHeight;
        int measuredWidth = resolveSizeAndState(batteryWidth, widthMeasureSpec, 0);//实际宽度
        int measuredHeight = resolveSizeAndState(batteryHeight, heightMeasureSpec, 0);//实际高度
        if (Math.abs(rotateAngle % 180) == 0) {
            //未旋转
            if (measuredWidth / (float) measuredHeight >= batteryWidth / (float) batteryHeight) {
                //如果宽高比大于默认的宽高比,那么使用高度的缩放比例
                scale = measuredHeight / (float) batteryHeight;
            } else {
                //如果宽高比小于默认的宽高比,那么使用宽度缩放比例
                scale = measuredWidth / (float) batteryWidth;
            }
        } else {
            //旋转了90度或者270度,电池的宽高调换
            if (measuredWidth / (float) measuredHeight >= batteryHeight / (float) batteryWidth) {
                scale = measuredHeight / (float) batteryWidth;
            } else {
                scale = measuredWidth / (float) batteryHeight;
            }
        }
        setMeasuredDimension(measuredWidth, measuredHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        canvas.save();
        canvas.translate((getWidth() / 2F), (getHeight() / 2F));
        canvas.rotate(rotateAngle);
        canvas.translate(-(getWidth() / 2F), -(getHeight() / 2F));

        //一.绘制电池外部的圆角矩形
        paint.reset();
        if (batteryPercent <= LOW_POWER_THRESHOLD && !isCharging) {
            //如果电量低于设置的低电量阈值,并且没有在充电的时候,电池外部框显示为红色
            paint.setColor(lowPowerColor);
        } else {
            paint.setColor(outRectColor);
        }
        paint.setStrokeWidth(outRectStrokeWidth * scale);
        paint.setStyle(Paint.Style.STROKE);
        //边框的宽度,供下方的计算方便使用,注意线太粗要减去边框,否则会超出范围
        float strokeWidth = outRectStrokeWidth * scale;
        //考虑到实际的宽高比例与要求的比例不一样,去除四边多余的部分
        float outLeft = (getWidth() - batteryWidth * scale) / 2F + strokeWidth / 2F;//先减去左边可能多余的空间,然后减去线条的半个线条粗
        float outRight = outLeft + outRectWidth * scale - strokeWidth;//left+外矩形的宽度,然后再减去整个线条粗
        float outTop = (getHeight() - batteryHeight * scale) / 2F + strokeWidth / 2F;//先减去上边可能多余的空间,然后减去线条的半个线条粗
        float outBottom = outTop + outRectHeight * scale - strokeWidth;//top+外矩形的高度,然后再减去整个线条粗
        canvas.drawRoundRect(outLeft, outTop, outRight, outBottom, outRectRound * scale, outRectRound * scale, paint);

        //二.绘制顶部的阳极,顺时针画线
        //1.计算边距
        float anodeLeft = outRight + strokeWidth / 2F;//注意加上外部的线宽的一半
        float anodeRight = anodeLeft + anodeWidth * scale;
        float anodeTop = (outTop + outBottom) / 2F - anodeHeight * scale / 2F;
        float anodeBottom = (outTop + outBottom) / 2F + anodeHeight * scale / 2F;

        paint.reset();
        anodePath.reset();
        paint.setStyle(Paint.Style.FILL);
        if (batteryPercent <= LOW_POWER_THRESHOLD && !isCharging) {
            //如果电量低于设置的低电量阈值,并且没有在充电的时候,电池外部框显示为红色
            paint.setColor(lowPowerColor);
        } else {
            paint.setColor(outRectColor);
        }
        anodePath.moveTo(anodeLeft, anodeTop);//笔尖移动到阳极小矩形的左上起始点,绝对坐标
        //2.绘制正极右上角的圆弧
        anodePath.arcTo(anodeRight - anodeRound * scale * 2,
                anodeTop,
                anodeRight,
                anodeTop + anodeRound * scale * 2,
                -90, //右上角圆弧起始角度
                90,
                false);//是否留下移动的痕迹,false:直接连线连到弧形起点（有痕迹）
        //3.绘制正极右下角的圆弧
        anodePath.arcTo(anodeRight - anodeRound * scale * 2,
                anodeBottom - anodeRound * scale * 2,
                anodeRight,
                anodeBottom,
                0,
                90,
                false);
        //4.连线到左下角
        anodePath.lineTo(anodeLeft, anodeBottom);
        canvas.drawPath(anodePath, paint);

        //三,画内部的矩形,根据电量百分比绘制
        paint.reset();
        paint.setStyle(Paint.Style.FILL);
        float innerCenterX = (outLeft + outRight) / 2F;
        float innerCenterY = (outTop + outBottom) / 2F;
        float innerLeft = innerCenterX - innerRectWidth * scale / 2F;
        float innerTop = innerCenterY - innerRectHeight * scale / 2F;
        float innerBottom = innerTop + innerRectHeight * scale;
        float innerRight;
        if (isCharging) {
            //充电时的,改变颜色,并且显示充电动画
            paint.setColor(chargeColor);
            innerRight = innerLeft + innerRectWidth * scale * chargePercent;//根据电量百分比,决定内部矩形最终的宽度
        } else {
            //非充电时,显示当前电量的矩形
            if (batteryPercent <= LOW_POWER_THRESHOLD) {
                paint.setColor(lowPowerColor);
            } else {
                paint.setColor(innerRectColor);
            }
            innerRight = innerLeft + innerRectWidth * scale * batteryPercent / 100F;//根据电量百分比,决定内部矩形最终的宽度
        }
        canvas.drawRect(innerLeft, innerTop, innerRight, innerBottom, paint);

        canvas.restore();
    }

    public void startCharge() {
        getAnimator().start();
        isCharging = true;
        invalidate();
    }

    public void stopCharge() {
        getAnimator().cancel();
        isCharging = false;
        invalidate();
    }

    private ObjectAnimator getAnimator() {
        if (animator == null) {
            animator = ObjectAnimator.ofFloat(this, "chargePercent", 0.01F, 1F);
        }
        animator.setDuration(5000);
        animator.setRepeatCount(Animation.INFINITE);
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                invalidate();
            }
        });
        return animator;
    }

    /**
     * 设置当前电量百分比
     *
     * @param batteryPercent
     */
    public void setBatteryPercent(int batteryPercent) {
        if (batteryPercent > 100 || batteryPercent < 0) {
            LogUtils.e("非法的电量百分比 batteryPercent: " + batteryPercent);
            return;
        }
        this.batteryPercent = batteryPercent;
        invalidate();
    }

    private float getChargePercent() {
        return chargePercent;
    }

    private void setChargePercent(float chargePercent) {
        this.chargePercent = chargePercent;
    }
}
